package network

import (
	"fmt"
	"net"
	"strings"
	"sync"
	"time"
)

// Connection 表示一个客户端连接
type Connection struct {
	ID       string
	Conn     net.Conn
	Address  string
	Protocol string
	IsActive bool
	mutex    sync.RWMutex

	OnDataReceived func(data []byte)
	OnDisconnected func()
}

// NewConnection 创建新的连接实例
func NewConnection(id string, conn net.Conn, protocol string) *Connection {
	return &Connection{
		ID:       id,
		Conn:     conn,
		Address:  conn.RemoteAddr().String(),
		Protocol: protocol,
		IsActive: true,
	}
}

// Send 发送数据到客户端
func (c *Connection) Send(data []byte) error {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	if !c.IsActive || c.Conn == nil {
		return fmt.Errorf("连接已断开")
	}

	_, err := c.Conn.Write(data)
	if err != nil {
		c.IsActive = false
		if c.OnDisconnected != nil {
			c.OnDisconnected()
		}
		return fmt.Errorf("发送数据失败: %v", err)
	}

	return nil
}

// SendString 发送字符串数据
func (c *Connection) SendString(data string) error {
	return c.Send([]byte(data))
}

// Close 关闭连接
func (c *Connection) Close() error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	if !c.IsActive || c.Conn == nil {
		return nil
	}

	c.IsActive = false
	err := c.Conn.Close()

	if c.OnDisconnected != nil {
		c.OnDisconnected()
	}

	return err
}

// Server 表示一个网络服务器
type Server struct {
	listener    net.Listener
	udpConn     *net.UDPConn
	port        string
	protocol    string
	isRunning   bool
	connections map[string]*Connection
	mutex       sync.RWMutex

	// 回调函数
	OnStarted            func()
	OnStopped            func()
	OnClientConnected    func(conn *Connection)
	OnClientDisconnected func(conn *Connection)
	OnDataReceived       func(conn *Connection, data []byte)
	OnError              func(err error)
}

// NewServer 创建新的服务器实例
func NewServer() *Server {
	return &Server{
		connections: make(map[string]*Connection),
		isRunning:   false,
	}
}

// Start 启动服务器
func (s *Server) Start(port, protocol string) error {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if s.isRunning {
		return fmt.Errorf("服务器已在运行")
	}

	s.port = port
	s.protocol = strings.ToUpper(protocol)

	var err error

	switch s.protocol {
	case "TCP":
		err = s.startTCP()
	case "UDP":
		err = s.startUDP()
	default:
		return fmt.Errorf("不支持的协议: %s", protocol)
	}

	if err != nil {
		if s.OnError != nil {
			s.OnError(err)
		}
		return err
	}

	s.isRunning = true

	if s.OnStarted != nil {
		s.OnStarted()
	}

	// 启动监听协程
	go s.acceptConnections()

	return nil
}

// startTCP 启动TCP服务器
func (s *Server) startTCP() error {
	address := fmt.Sprintf(":%s", s.port)
	listener, err := net.Listen("tcp", address)
	if err != nil {
		return fmt.Errorf("TCP服务器启动失败: %v", err)
	}

	s.listener = listener
	return nil
}

// startUDP 启动UDP服务器
func (s *Server) startUDP() error {
	address := fmt.Sprintf(":%s", s.port)
	udpAddr, err := net.ResolveUDPAddr("udp", address)
	if err != nil {
		return fmt.Errorf("UDP地址解析失败: %v", err)
	}

	conn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		return fmt.Errorf("UDP服务器启动失败: %v", err)
	}

	s.udpConn = conn
	return nil
}

// Stop 停止服务器
func (s *Server) Stop() error {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	if !s.isRunning {
		return nil
	}

	// 先设置为停止状态，防止acceptConnections协程报错
	s.isRunning = false

	// 关闭所有客户端连接
	for _, conn := range s.connections {
		conn.Close()
	}
	s.connections = make(map[string]*Connection)

	// 关闭监听器
	if s.listener != nil {
		s.listener.Close()
		s.listener = nil
	}

	if s.udpConn != nil {
		s.udpConn.Close()
		s.udpConn = nil
	}

	if s.OnStopped != nil {
		s.OnStopped()
	}

	return nil
}

// acceptConnections 接受连接的协程
func (s *Server) acceptConnections() {
	if s.protocol == "TCP" {
		s.acceptTCPConnections()
	} else if s.protocol == "UDP" {
		s.acceptUDPConnections()
	}
}

// acceptTCPConnections 接受TCP连接
func (s *Server) acceptTCPConnections() {
	for s.isRunning {
		conn, err := s.listener.Accept()
		if err != nil {
			if s.isRunning && s.OnError != nil {
				s.OnError(err)
			}
			break
		}

		// 创建新连接
		connectionID := fmt.Sprintf("tcp_%s_%d", conn.RemoteAddr().String(), time.Now().UnixNano())
		connection := NewConnection(connectionID, conn, "TCP")

		// 设置回调
		connection.OnDataReceived = func(data []byte) {
			if s.OnDataReceived != nil {
				s.OnDataReceived(connection, data)
			}
		}

		connection.OnDisconnected = func() {
			s.removeConnection(connectionID)
			if s.OnClientDisconnected != nil {
				s.OnClientDisconnected(connection)
			}
		}

		// 添加到连接列表
		s.addConnection(connectionID, connection)

		// 通知新连接
		if s.OnClientConnected != nil {
			s.OnClientConnected(connection)
		}

		// 启动数据接收协程
		go s.receiveTCPData(connection)
	}
}

// acceptUDPConnections 接受UDP连接
func (s *Server) acceptUDPConnections() {
	buffer := make([]byte, 4096)

	for s.isRunning {
		n, remoteAddr, err := s.udpConn.ReadFromUDP(buffer)
		if err != nil {
			if s.isRunning && s.OnError != nil {
				s.OnError(err)
			}
			break
		}

		// 为UDP创建虚拟连接
		connectionID := fmt.Sprintf("udp_%s", remoteAddr.String())

		s.mutex.RLock()
		connection, exists := s.connections[connectionID]
		s.mutex.RUnlock()

		if !exists {
			// 创建新的UDP连接
			connection = &Connection{
				ID:       connectionID,
				Address:  remoteAddr.String(),
				Protocol: "UDP",
				IsActive: true,
			}

			// 设置回调
			connection.OnDataReceived = func(data []byte) {
				if s.OnDataReceived != nil {
					s.OnDataReceived(connection, data)
				}
			}

			connection.OnDisconnected = func() {
				s.removeConnection(connectionID)
				if s.OnClientDisconnected != nil {
					s.OnClientDisconnected(connection)
				}
			}

			// 添加到连接列表
			s.addConnection(connectionID, connection)

			// 通知新连接
			if s.OnClientConnected != nil {
				s.OnClientConnected(connection)
			}
		}

		// 处理接收到的数据
		if n > 0 {
			data := make([]byte, n)
			copy(data, buffer[:n])

			// 直接调用数据接收回调，确保每个UDP包都被处理
			if s.OnDataReceived != nil {
				s.OnDataReceived(connection, data)
			}
		}
	}
}

// receiveTCPData 接收TCP数据的协程
func (s *Server) receiveTCPData(conn *Connection) {
	buffer := make([]byte, 4096)

	for conn.IsActive {
		// 设置读取超时
		err := conn.Conn.SetReadDeadline(time.Now().Add(1 * time.Second))
		if err != nil {
			break
		}

		n, err := conn.Conn.Read(buffer)
		if err != nil {
			break
		}

		if n > 0 && conn.OnDataReceived != nil {
			data := make([]byte, n)
			copy(data, buffer[:n])
			conn.OnDataReceived(data)
		}
	}

	// 连接断开
	conn.Close()
}

// addConnection 添加连接
func (s *Server) addConnection(id string, conn *Connection) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	s.connections[id] = conn
}

// removeConnection 移除连接
func (s *Server) removeConnection(id string) {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	delete(s.connections, id)
}

// GetConnections 获取所有连接
func (s *Server) GetConnections() []*Connection {
	s.mutex.RLock()
	defer s.mutex.RUnlock()

	connections := make([]*Connection, 0, len(s.connections))
	for _, conn := range s.connections {
		connections = append(connections, conn)
	}

	return connections
}

// DisconnectClient 断开指定客户端
func (s *Server) DisconnectClient(connectionID string) error {
	s.mutex.RLock()
	conn, exists := s.connections[connectionID]
	s.mutex.RUnlock()

	if !exists {
		return fmt.Errorf("连接不存在: %s", connectionID)
	}

	return conn.Close()
}

// SendToClient 向指定客户端发送数据
func (s *Server) SendToClient(connectionID string, data []byte) error {
	s.mutex.RLock()
	conn, exists := s.connections[connectionID]
	s.mutex.RUnlock()

	if !exists {
		return fmt.Errorf("连接不存在: %s", connectionID)
	}

	return conn.Send(data)
}

// SendToAll 向所有客户端发送数据
func (s *Server) SendToAll(data []byte) {
	s.mutex.RLock()
	connections := make([]*Connection, 0, len(s.connections))
	for _, conn := range s.connections {
		connections = append(connections, conn)
	}
	s.mutex.RUnlock()

	for _, conn := range connections {
		conn.Send(data)
	}
}

// IsRunning 检查服务器是否运行
func (s *Server) IsRunning() bool {
	s.mutex.RLock()
	defer s.mutex.RUnlock()
	return s.isRunning
}

// GetServerInfo 获取服务器信息
func (s *Server) GetServerInfo() (string, string) {
	s.mutex.RLock()
	defer s.mutex.RUnlock()
	return s.port, s.protocol
}
